/* 
 ********************************************************************
 * Project:     ethernet driver for LPC23xx/24xx
 * File:    	ethernet_lpc23xx.h
 *
 * System:   	ARM7TDMI-S 32 Bit
 * Compiler:  	GCC 4.0.3
 *
 * Date:      	2006-08-31
 * Author:    	Wenz
 *
 * Rights:    	Hitex Development Tools GmbH
 *            	Greschbachstr. 12
 *            	D-76229 Karlsruhe
 ********************************************************************
 * Description:
 *	
 * interface to the ethernet driver for LPC23xx controller
 ********************************************************************
 * History:
 *
 *  Revision 1.0    2006/09/27      We
 *     Initial revision 
 ********************************************************************
 * This software is provided by the author 'AS IS' without any 
 * warranties. Hitex Development Tools GmbH shall not be held 
 * liable for any direct, indirect or consequential damages with
 * respect to any claims arising from the content of such software.
 ********************************************************************/


#if !defined _ETHERNET_LPC23XX_H
#define		_ETHENET_LPC23XX_H

#include "defines.h"
#include "peripherals_config.h"


/* MAC1 & MAC2 register */

#define MAC1_REC_EN         0x00000001  /* Receive Enable                    */
#define MAC1_PASS_ALL       0x00000002  /* Pass All Receive Frames           */
#define MAC1_RX_FLOWC       0x00000004  /* RX Flow Control                   */
#define MAC1_TX_FLOWC       0x00000008  /* TX Flow Control                   */
#define MAC1_LOOPB          0x00000010  /* Loop Back Mode                    */
#define MAC1_RES_TX         0x00000100  /* Reset TX Logic                    */
#define MAC1_RES_MCS_TX     0x00000200  /* Reset MAC TX Control Sublayer     */
#define MAC1_RES_RX         0x00000400  /* Reset RX Logic                    */
#define MAC1_RES_MCS_RX     0x00000800  /* Reset MAC RX Control Sublayer     */
#define MAC1_SIM_RES        0x00004000  /* Simulation Reset                  */
#define MAC1_SOFT_RES       0x00008000  /* Soft Reset MAC                    */


#define MAC2_FDPX_ENA		0x00000001	/* full duplex mode enable */
#define MAC2_FRM_LEN_CHK    0x00000002  /* Frame Length Checking             */
#define MAC2_HUGE_FRM_EN    0x00000004  /* Huge Frame Enable                 */
#define MAC2_DLY_CRC        0x00000008  /* Delayed CRC Mode                  */
#define MAC2_CRC_EN         0x00000010  /* Append CRC to every Frame         */
#define MAC2_PAD_EN         0x00000020  /* Pad all Short Frames              */
#define MAC2_VLAN_PAD_EN    0x00000040  /* VLAN Pad Enable                   */
#define MAC2_ADET_PAD_EN    0x00000080  /* Auto Detect Pad Enable            */
#define MAC2_PPREAM_ENF     0x00000100  /* Pure Preamble Enforcement         */
#define MAC2_LPREAM_ENF     0x00000200  /* Long Preamble Enforcement         */
#define MAC2_NO_BACKOFF     0x00001000  /* No Backoff Algorithm              */
#define MAC2_BACK_PRESSURE  0x00002000  /* Backoff Presurre / No Backoff     */
#define MAC2_EXCESS_DEF     0x00004000  /* Excess Defer                      */


/* Back-to-Back Inter-Packet-Gap Register ETH_IPGT */

#define IPGT_FULL_DUP   0x00000015  /* Recommended value for Full Duplex */
#define IPGT_HALF_DUP   0x00000012  /* Recommended value for Half Duplex */


/* Non Back-to-Back Inter-Packet-Gap Register ETH_IPGR (10 MBit mode)	*/

#define IPGR_DEF			0x12		/* 960 ns */

/* Collision window retry register					*/

#define CLRT_RETRANSMAX		0x0F
#define CLRT_COLLWINDOW		0x37 << 8


/* Maximum Frame Register  */												
#define ETH_MAX_FLEN        1536        /* Max. Ethernet Frame Size          */


/* PHY Support Register ETH_PHYSUPP */
#define SUPP_SPEED_100      0x00000100  /* Reduced MII Logic Current Speed   */
#define SUPP_RES_RMII       0x00000800  /* Reset Reduced MII Logic           */




/* Command Register */
#define CR_RX_EN            0x00000001  /* Enable Receive                    */
#define CR_TX_EN            0x00000002  /* Enable Transmit                   */
#define CR_REG_RES          0x00000008  /* Reset Host Registers              */
#define CR_TX_RES           0x00000010  /* Reset Transmit Datapath           */
#define CR_RX_RES           0x00000020  /* Reset Receive Datapath            */
#define CR_PASS_RUNT_FRM    0x00000040  /* Pass Runt Frames                  */
#define CR_PASS_RX_FILT     0x00000080  /* Pass RX Filter                    */
#define CR_TX_FLOW_CTRL     0x00000100  /* TX Flow Control                   */
#define CR_RMII             0x00000200  /* Reduced MII Interface             */
#define CR_FULL_DUP         0x00000400  /* Full Duplex                       */


/* Receive Filter Control Register */

#define RFC_UCAST_EN        0x00000001  /* Accept Unicast Frames Enable      */
#define RFC_BCAST_EN        0x00000002  /* Accept Broadcast Frames Enable    */
#define RFC_MCAST_EN        0x00000004  /* Accept Multicast Frames Enable    */
#define RFC_UCAST_HASH_EN   0x00000008  /* Accept Unicast Hash Filter Frames */
#define RFC_MCAST_HASH_EN   0x00000010  /* Accept Multicast Hash Filter Fram.*/
#define RFC_PERFECT_EN      0x00000020  /* Accept Perfect Match Enable       */
#define RFC_MAGP_WOL_EN     0x00001000  /* Magic Packet Filter WoL Enable    */
#define RFC_PFILT_WOL_EN    0x00002000  /* Perfect Filter WoL Enable         */

/* Interrupt Status/Enable/Clear/Set Registers */
#define INT_RX_OVERRUN      0x00000001  /* Overrun Error in RX Queue         */
#define INT_RX_ERR          0x00000002  /* Receive Error                     */
#define INT_RX_FIN          0x00000004  /* RX Finished Process Descriptors   */
#define INT_RX_DONE         0x00000008  /* Receive Done                      */
#define INT_TX_UNDERRUN     0x00000010  /* Transmit Underrun                 */
#define INT_TX_ERR          0x00000020  /* Transmit Error                    */
#define INT_TX_FIN          0x00000040  /* TX Finished Process Descriptors   */
#define INT_TX_DONE         0x00000080  /* Transmit Done                     */
#define INT_SOFT_INT        0x00001000  /* Software Triggered Interrupt      */
#define INT_WAKEUP          0x00002000  /* Wakeup Event Interrupt            */



// PHY register offsets of DP8348C

#define	PHY_DEVICE_NO_1		1
#define PHY_DEVICE_1_ADR	PHY_DEVICE_NO_1 << 8

#define PHY_BMCR			0			/* Basic Mode Control Register       */
#define PHY_BMSR			1			/* Basic Mode Status Register        */
#define PHY_IDR1			2			/* PHY Identifier 1                  */
#define PHY_IDR2			3			/* PHY Identifier 2                  */
#define PHY_ANAR			4			/* Auto-Negotiation Advertisement    */
#define PHY_ANLPAR			5			/* Auto-Neg. Link Partner Abitily    */
#define PHY_ANER			6			/* Auto-Neg. Expansion Register      */
#define PHY_ANNPTR			7			/* Auto-Neg. Next Page TX            */

/* PHY Extended Registers */
#define PHY_STS				0x10        /* Status Register                   */
#define PHY_MICR			0x11        /* MII Interrupt Control Register    */
#define PHY_MISR			0x12        /* MII Interrupt Status Register     */
#define PHY_FCSCR			0x14        /* False Carrier Sense Counter       */
#define PHY_RECR			0x15        /* Receive Error Counter             */
#define PHY_PCSR			0x16        /* PCS Sublayer Config. and Status   */
#define PHY_RBR				0x17        /* RMII and Bypass Register          */
#define PHY_LEDCR			0x18        /* LED Direct Control Register       */
#define PHY_PHYCR			0x19        /* PHY Control Register              */
#define PHY_10BTSCR			0x1A        /* 10Base-T Status/Control Register  */
#define PHY_CDCTRL1			0x1B        /* CD Test Control and BIST Extens.  */
#define PHY_EDCR			0x1D        /* Energy Detect Control Register    */

/* BMCR setting */
#define PHY_RESET			0x8000
#define PHY_POWERDOWN		0x0800
#define PHY_ISOLATE			0x0400
#define PHY_FULLD_100M      0x2100      /* Full Duplex 100Mbit               */
#define PHY_HALFD_100M      0x2000      /* Half Duplex 100Mbit               */
#define PHY_FULLD_10M       0x0100      /* Full Duplex 10Mbit                */
#define PHY_RESTART_AUTON	0x0200		/* restart autonegotiation			 */
#define PHY_HALFD_10M       0x0000      /* Half Duplex 10MBit                */
#define PHY_AUTO_NEG        0x1000      /* Select Auto Negotiation           */
#define PHY_LOOPBACK		0x4000		/* loppback mode					 */

/* BMSR status */
#define PHY_100BE_T4		0x8000
#define PHY_100TX_FULL		0x4000
#define PHY_100TX_HALF		0x2000
#define PHY_10BE_FULL		0x1000
#define PHY_10BE_HALF		0x0800
#define PHY_AUTO_DONE		0x0020
#define PHY_REMOTE_FAULT	0x0010
#define PHY_NO_AUTO			0x0008
#define PHY_LINK_ESTABLISHED 0x0004

/* extended status register */

#define PHY_EXST_LINK_ESTABLISHED	0x0001
#define PHY_EXST_SPEED_10M			0x0002
#define PHY_EXST_FDX				0x0004
#define PHY_EXST_LOOPBACK			0x0008
#define PHY_EXST_AUTONEG_COMPLETE	0x0010
#define PHY_EXST_JABBER_DETECT		0x0020


#define DP83848C_DEF_ADR    0x0100      /* Default PHY device address        */
#define DP83848C_ID         0x20005C90  /* PHY Identifier                    */

typedef enum
{
	NOLINKSTATE = 0x00,
	LINK_OFF,
	LINK_ON
} 
linkstatus;



/* MII Indicator register BIT No definitions    */

#define MII_IND_BUSY		0
#define MII_IND_SCAN		1
#define MII_IND_INVALID		2
#define MII_IND_LINKFAIL	3



/* structs declaring the DMA descriptor tables    */

/* receive descriptor struct */
typedef struct  
{
	uint8_t*	packet;
	uint32_t	control;
}
receiveDescr;

/* Control Bit definitions						*/

#define RX_CONTROL_INT		0x80000000		/* receive Fragment produces interrupt */


/* Receive status struct */
typedef struct  
{
	uint32_t	info;
	uint32_t	hashCRC;
}
receiveStatus;

/* RX Status Information Word */
#define RS_INFO_SIZE          0x000007FF  /* Data size in bytes                */
#define RS_INFO_CTRL_FRAME    0x00040000  /* Control Frame                     */
#define RS_INFO_VLAN          0x00080000  /* VLAN Frame                        */
#define RS_INFO_FAIL_FILT     0x00100000  /* RX Filter Failed                  */
#define RS_INFO_MCAST         0x00200000  /* Multicast Frame                   */
#define RS_INFO_BCAST         0x00400000  /* Broadcast Frame                   */
#define RS_INFO_CRC_ERR       0x00800000  /* CRC Error in Frame                */
#define RS_INFO_SYM_ERR       0x01000000  /* Symbol Error from PHY             */
#define RS_INFO_LEN_ERR       0x02000000  /* Length Error                      */
#define RS_INFO_RANGE_ERR     0x04000000  /* Range Error (exceeded max. size)  */
#define RS_INFO_ALIGN_ERR     0x08000000  /* Alignment Error                   */
#define RS_INFO_OVERRUN       0x10000000  /* Receive overrun                   */
#define RS_INFO_NO_DESCR      0x20000000  /* No new Descriptor available       */
#define RS_INFO_LAST_FLAG     0x40000000  /* Last Fragment in Frame            */
#define RS_INFO_ERR           0x80000000  /* Error Occured (OR of all errors)  */

#define RS_INFO_ERR_MASK     (	RS_INFO_FAIL_FILT | \
								RS_INFO_CRC_ERR   | \
								RS_INFO_SYM_ERR	  | \
								RS_INFO_LEN_ERR   | \
								RS_INFO_ALIGN_ERR | \
								RS_INFO_OVERRUN)

/* transmit descriptor struct */
typedef struct  
{
	uint8_t*	packet;
	uint32_t	control;
}
transmitDescr;


typedef struct  
{
	uint32_t	status;
}
transmitStatus;

/* Transmit Control word */
#define TC_LAST_FLAG     0x40000000		/* Last Fragment in Frame            */
#define TX_CONTROL_INT	 0x80000000		/* transmit Fragment produces interrupt */


/****************************************************************************
* Name:			eth_data
*                  	
* Description:	complete structure for the decriptors and the data buffers  	
*				This struct will be placed directly at start of the Ethernet
*				RAM. 
*						
****************************************************************************
*/

typedef struct
{
	receiveDescr	xRxDescr[NUMBER_REC_FRAGMENTS];	
	receiveStatus	xRxStat[NUMBER_REC_FRAGMENTS];
	transmitDescr	xTxDescr[NUMBER_TX_FRAGMENTS];
	transmitStatus	xTxStat[NUMBER_TX_FRAGMENTS];
	uint8_t			ucRxBuffer[NUMBER_REC_FRAGMENTS][MAXLENGTH_REC_FRAGMENT];
	uint8_t			ucTxBuffer[NUMBER_TX_FRAGMENTS][MAXLENGTH_TX_FRAGMENT];
}
eth_data;



/**************************************
 * user API 
 ***************************************/



typedef struct
{
	uint32_t	Length;
	uint8_t*	pReceived;
	uint32_t	status;
}
fragment; 

#define FRAMECOMPLETE	0x01
#define FRAMEERROR		0x02


/**************************************
 * interrupt interface
 ***************************************/

/* define the interrupt source */
#define INT_SOURCE_ETH		21

/* macros for enable and disable */
#define prvEnableEthInterrupt()		VICIntEnable = (0x01 << INT_SOURCE_ETH) 
#define prvDisableEthInterrupt()	VICIntEnClr = (0x01 << INT_SOURCE_ETH) 

/* macro to acknowledge the INT */
#define prvIntAck()	VICVectAddr=0


/* external function declarations */

extern bool		eEthInit(void);
extern uint32_t	ulReadFrame(uint8_t* aFrameBuffer);
extern bool		eEthSendFrame(uint32_t frameLength, uint8_t* aFrameBuffer);
extern void		vEthSetStationAddress( uint8_t*	pAddress);
extern linkstatus eGetLinkStatus(uint32_t	aPHYDevice);


#endif
/*----------------------------------------------------------------------------
 * end of file
 *---------------------------------------------------------------------------*/
